/**
 * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
 * This file is part of CSipSimple.
 *
 *  CSipSimple is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  If you own a pjsip commercial license you can also redistribute it
 *  and/or modify it under the terms of the GNU Lesser General Public License
 *  as an android library.
 *
 *  CSipSimple is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with CSipSimple.  If not, see <http://www.gnu.org/licenses/>.
 *  
 *  This file and this file only is also released under Apache license as an API file
 */

package com.cloudptt.api.pjsip.api;

import android.os.RemoteException;

import com.cloudptt.api.pjsua2.api.IPjsuaService;

/**
 * Manage SIP application globally <br/>
 * Define intent, action, broadcast, extra constants <br/>
 * It also define authority and uris for some content holds by the internal
 * database
 */
public final class SipManager {
	// -------
	// Static constants
	// PERMISSION
	/**
	 * Permission that allows to use sip : place call, control call etc.
	 */
	public static final String PERMISSION_USE_SIP = "android.permission.USE_SIP";
	/**
	 * Permission that allows to configure sip engine : preferences, accounts.
	 */
	public static final String PERMISSION_CONFIGURE_SIP = "android.permission.CONFIGURE_SIP_MC";

	// SERVICE intents
	/**
	 * Used to bind sip service to configure it.<br/>
	 * This method has been deprected and should not be used anymore. <br/>
	 * Use content provider approach instead
	 * 
	 * @see SipConfigManager
	 */
	public static final String INTENT_SIP_CONFIGURATION = "com.huhu.service.SipConfiguration";
	/**
	 * Bind sip service to control calls.<br/>
	 * If you start the service using {@link android.content.Context#startService(android.content.Intent intent)}
	 * , you may want to pass {@link #EXTRA_OUTGOING_ACTIVITY} to specify you
	 * are starting the service in order to make outgoing calls. You are then in
	 * charge to unregister for outgoing calls when user finish with your
	 * activity or when you are not anymore in calls using
	 * {@link #ACTION_OUTGOING_UNREGISTER}<br/>
	 * If you actually make a call or ask service to do something but wants to
	 * unregister, you must defer unregister of your activity using
	 * {@link #ACTION_DEFER_OUTGOING_UNREGISTER}.
	 * 
	 * @see ISipService
	 * @see #EXTRA_OUTGOING_ACTIVITY
	 */
	public static final String INTENT_SIP_SERVICE = "PjsuaService";
	public static final String INTENT_KEEPALIVE_SERVICE = "KeepAliveService";
	public static final String EXTERA = "who";

	/**
	 * Scheme for csip uri.
	 */
	public static final String PROTOCOL_CSIP = "csip";
	/**
	 * Scheme for sip uri.
	 */
	public static final String PROTOCOL_SIP = "sip";
	/**
	 * Scheme for sips (sip+tls) uri.
	 */
	public static final String PROTOCOL_SIPS = "sips";
	/**
	 * Broadcast sent when call state has changed.
	 * <p>
	 * Provided extras :
	 * <ul>
	 * <li>{@link #EXTRA_CALL_INFO} a {@link SipCallSession} containing infos of
	 * the call</li>
	 * </ul>
	 * </p>
	 */
	public static final String ACTION_SIP_STACK_CHANGED = "com.huhu.service.SIPSTACK_CHANGED";
	public static final String SIPSTACK_STATUS = "status";
	public static final int SIPSTACK_START = 1;
	public static final int SIPSTACK_STOP = 2;

	public static final String ACTION_SIP_REG = "com.huhu.service.REGISTER";
	public static final String RESULT    ="result";
	public static final String RESULT_CODE    ="code";
	public static final String RESULT_NUM    ="num";
	public static final String RESULT_NAME    ="name";
	public static final String EXT_STR    ="Extension";
//	public static final String ACTION_SIP_RELOGIN = "com.huhu.service.RELOGIN";
	public static final String ACTION_SIP_FOREDETACH = "com.huhu.service.FOREDETACH";
	public static final String ACTION_SIP_SVR_RESTART = "com.huhu.service.SVR_RESTART";
	public static final String ACTION_SIP_KEEPALIVE = "com.huhu.service.KEEPALIVE";

	
	public static final String ACTION_SINGLE_CALL_INCOMING = "com.huhu.service.SINGLE_CALL_INCOMING";
	public static final String ACTION_SINGLE_CALL_INFO = "com.huhu.service.SINGLE_CALL_INFO";
	
//	public static final String ACTION_WEBRTC_CALL_MAKE = "com.huhu.service.WEBRTC_CALL_MAKE";
	public static final String ACTION_WEBRTC_CALL_INCOMING = "com.huhu.service.WEBRTC_CALL_INCOMING";
	public static final String ACTION_WEBRTC_CALL_INFO = "com.huhu.service.WEBRTC_CALL_INFO";
	public static final String ACTION_WEBRTC_CALL_CANDIDATE = "com.huhu.service.WEBRTC_CALL_CANDIDATE";
	public static final String ACTION_CALL_NOTIFY_BAR = "com.huhu.service.ACTION_CALL_NOTIFY";
	
	
	public static final String ACTION_SIP_CALL_INCOMING = "com.huhu.service.CALL_INCOMING";
	public static final String ACTION_SIP_CALL_CHANGED = "com.huhu.service.CALL_CHANGED";
	public static final String ACTION_SIP_MEDIA_CHANGED = "com.huhu.service.MEDIA_CHANGED";
	public static final String ACTION_SIP_SPEAKING_CHANGED = "com.huhu.service.SPEAKING_CHANGED";

	public static final String ACTION_VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
//	public static final String ACTION_MESSAGECOUNT_CHANGED = "android.huhu.service.MESSAGECOUNT_CHANGED_ACTION";

//	public static final String ACTION_APP_ForceDetach = "com.huhu.service.FORCEDETCH";
	public static final String ACTION_NETWORK_CHANGED = "com.huhu.service.NETWORKD_CHANGED";
	public static final String NETWORK_STATUS = "status";

	public static final String ACTION_PTT_ACTION = "com.huhu.service.PTT_ACTION";

	public static final String ACTION_SIP_ADDR_UPT = "com.huhu.service.ADDR_UPT";
	public static final String ACTION_SIP_ONLINE = "com.huhu.service.ONLINE";
	public static final String ACTION_SIP_CALL_LOG = "com.huhu.service.CALL_LOG";
	public static final String ACTION_SIP_MESSAGE = "com.huhu.service.MESSAGE";
	public static final String Body_Str    ="body";
	public static final String Notify_Str    ="notify";
	public static final String Info_Str    ="info";
	public static final String LOCATION_XML    ="location_xml";
	public static final String FROML_STR    ="from";
//	public static final String SENDER_STR    ="sender";
//	public static final String SESSION_TYPE_STR    ="session_type";
//	public static final String MSG_TYPE_STR    ="msg_type";
	public static final String ACTION_SIP_MESSAGE_SYS = "com.huhu.service.MESSAGE_SYS";
	public static final String MSG_TYPE ="type";
	
	public static final String MSG_CANDIDATE ="text/candidate";
	public static final String MSG_Nofity ="text/notify";
	public static final String MSG_MSG ="application/json";
	
	public static final int MSG_TYPE_TXT = 1;
	public static final int MSG_TYPE_FILE = 2;
	public static final int MSG_TYPE_NOTIFY = 3;
	
	public static final String ACTION_SIP_NOTIFY = "com.huhu.service.NOTIFY";
	public static final String CONTENT    ="content";

	public static final String ACTION_SIP_SOS = "com.huhu.service.SOS";

	public static final String ACTION_SIP_APPLOG = "com.huhu.service.APPLOG";
	
	public static final String ACTION_SIP_MSG_SYS_NOTIFY_ADDR = "com.huhu.service.SYS_NOTIFY_ADDR";
	public static final String SYS_NOTIFY_TYPE_STR    ="sys_notify_type";
	public static final String ACTION_SIP_MESSAGE_Distribute = "com.huhu.service.MESSAGE_LOCATION";
	public static final String XML_OBJ    ="obj";
	
	public static final String ACTION_SIP_REGISTER_TIMEOUT = "com.huhu.service.REGISTER.TIMEOUT";
	
	

	//GPS相关设置
	public static final String ACTION_LBS_SETTING_CHANGED = "com.ptt.setting.ACTION_LBS_SETTING_CHANGED";
	public static final String ACTION_LBS_CHANGED 		  = "com.ptt.lbs.ACTION_LBS_CHANGED";
	public static final String ACTION_LBS_RECEIVE_ACK_MSG =  "com.ptt.lbs.ACTION_LBS_RECEIVE_ACK_MSG";
	public final static String EXTRA_VOICE_REPORT = "voice_report";
	public static final String ACTION_LBS_SETTING_SAVE = "com.ptt.setting.ACTION_LBS_SETTING_SAVE";
	public static final String ACTION_LBS_MESSAGE = "com.ptt.lbs.ACTION_LBS_MESSAGE";
	public static final String ACTION_SYS_NOTIFY = "com.ptt.sys.ACTION_SYS_NOFITY";
//	public static final String ACTION_SYS_PUBLISH = "com.ptt.sys.ACTION_SYS_PUBLISH";
	public static final String MSG_MSG_CODE ="msg_code";
	public static final String MSG_MC_TYPE ="mc_type";

	/**
	 * Broadcast sent when a conversation has been recorded.<br/>
	 * This is linked to the call record feature of CSipSimple available through {@link ISipService#startRecording(int)}
	 * <p>
	 * Provided extras :
	 * <ul>
	 * <li>{@link SipManager#EXTRA_FILE_PATH} the path to the recorded file</li>
	 * <li>{@link SipManager#EXTRA_CALL_INFO} the information on the call recorded</li>
	 * </ul>
	 * </p>
	 */
	public static final String ACTION_SIP_CALL_RECORDED = "com.huhu.service.CALL_RECORDED";
	/**
	 * Plugin action for themes.
	 */
	public static final String ACTION_GET_DRAWABLES = "com.huhu.themes.GET_DRAWABLES";

	/**
	 * Plugin action for call management extension. <br/>
	 * Any app that register this plugin and has rights to {@link #PERMISSION_USE_SIP} will appear 
	 * in the call cards. <br/>
	 * The activity entry in manifest may have following metadata
	 * <ul>
	 * <li>{@link #EXTRA_SIP_CALL_MIN_STATE} minimum call state for this plugin to be active. Default {@link SipCallSession.InvState#EARLY}.</li>
	 * <li>{@link #EXTRA_SIP_CALL_MAX_STATE} maximum call state for this plugin to be active. Default {@link SipCallSession.InvState#CONFIRMED}.</li>
	 * <li>{@link #EXTRA_SIP_CALL_CALL_WAY} bitmask flag for selecting only one way. 
	 *  {@link #BITMASK_IN} for incoming; 
	 *  {@link #BITMASK_OUT} for outgoing.
	 *  Default ({@link #BITMASK_IN} | {@link #BITMASK_OUT}) (any way).</li>
	 * </ul> 
	 * Receiver activity will get an extra with key {@value #EXTRA_CALL_INFO} with a {@link SipCallSession}.
	 */
	//    public static final String ACTION_INCALL_PLUGIN = "com.huhu.sipcall.action.HANDLE_CALL_PLUGIN";

	//    public static final String EXTRA_SIP_CALL_MIN_STATE = "com.huhu.sipcall.MIN_STATE";
	//    public static final String EXTRA_SIP_CALL_MAX_STATE = "com.huhu.sipcall.MAX_STATE";
	public static final String EXTRA_SIP_CALL_CALL_WAY = "com.huhu.sipcall.CALL_WAY";

	/**
	 * Bitmask to keep media/call coming from outside
	 */
	public final static int BITMASK_IN = 1 << 0;
	/**
	 * Bitmask to keep only media/call coming from the app
	 */
	public final static int BITMASK_OUT = 1 << 1;
	/**
	 * Bitmask to keep all media/call whatever incoming/outgoing
	 */
	public final static int BITMASK_ALL = BITMASK_IN | BITMASK_OUT;

	/**
	 * Plugin action for rewrite numbers. <br/>     
	 * You can expect {@link android.content.Intent#EXTRA_PHONE_NUMBER} as argument for the
	 * number to rewrite. <br/>
	 * Your receiver must
	 * {@link android.content.BroadcastReceiver#getResultExtras(boolean)} with parameter true to
	 * fill response. <br/>
	 * Your response contains :
	 * <ul>
	 * <li>{@link android.content.Intent#EXTRA_PHONE_NUMBER} with
	 * {@link java.lang.String} (optional) : Rewritten phone number.</li>
	 * </ul>
	 */
	//    public final static String ACTION_REWRITE_NUMBER = "com.huhu.phone.action.REWRITE_NUMBER"; 
	/**
	 * Plugin action for audio codec.
	 */
	public static final String ACTION_GET_EXTRA_CODECS = "com.huhu.codecs.action.REGISTER_CODEC";
	/**
	 * Plugin action for video codec.
	 */
	public static final String ACTION_GET_EXTRA_VIDEO_CODECS = "com.huhu.codecs.action.REGISTER_VIDEO_CODEC";
	/**
	 * Plugin action for video.
	 */
	public static final String ACTION_GET_VIDEO_PLUGIN = "com.huhu.plugins.action.REGISTER_VIDEO";
	/**
	 * Meta constant name for library name.
	 */
	public static final String META_LIB_NAME = "lib_name";
	/**
	 * Meta constant name for the factory name.
	 */
	public static final String META_LIB_INIT_FACTORY = "init_factory";
	/**
	 * Meta constant name for the factory deinit name.
	 */
	public static final String META_LIB_DEINIT_FACTORY = "deinit_factory";

	// Content provider
	/**
	 * Authority for regular database of the application.
	 */
	public static final String AUTHORITY = "com.huhu.db";
	/**
	 * Base content type for csipsimple objects.
	 */
	public static final String BASE_DIR_TYPE = "vnd.android.cursor.dir/vnd.csipsimple";
	/**
	 * Base item content type for csipsimple objects.
	 */
	public static final String BASE_ITEM_TYPE = "vnd.android.cursor.item/vnd.csipsimple";

	// Content Provider - call logs
	/**
	 * Table name for call logs.
	 */
//	public static final String CALLLOGS_TABLE_NAME = "calllogs";
//	/**
//	 * Content type for call logs provider.
//	 */
//	public static final String CALLLOG_CONTENT_TYPE = BASE_DIR_TYPE + ".calllog";
//	/**
//	 * Item type for call logs provider.
//	 */
//	public static final String CALLLOG_CONTENT_ITEM_TYPE = BASE_ITEM_TYPE + ".calllog";
//	/**
//	 * Uri for call log content provider.
//	 */
//	public static final Uri CALLLOG_URI = Uri.parse(ContentResolver.SCHEME_CONTENT + "://"
//			+ AUTHORITY + "/"
//			+ CALLLOGS_TABLE_NAME);
//	/**
//	 * Base uri for a specific call log. Should be appended with id of the call log.
//	 */
//	public static final Uri CALLLOG_ID_URI_BASE = Uri.parse(ContentResolver.SCHEME_CONTENT + "://"
//			+ AUTHORITY + "/"
//			+ CALLLOGS_TABLE_NAME + "/");
//	// -- Extra fields for call logs
//	/**
//	 * The account used for this call
//	 */
//	public static final String CALLLOG_PROFILE_ID_FIELD = "account_id";
//	/**
//	 * The final latest status code for this call.
//	 */
//	public static final String CALLLOG_STATUS_CODE_FIELD = "status_code";
//	/**
//	 * The final latest status text for this call.
//	 */
//	public static final String CALLLOG_STATUS_TEXT_FIELD = "status_text";

	// Content Provider - filter
	/**
	 * Table name for filters/rewriting rules.
	 */
//	public static final String FILTERS_TABLE_NAME = "outgoing_filters";
	/**
	 * Content type for filter provider.
	 */
	public static final String FILTER_CONTENT_TYPE = BASE_DIR_TYPE + ".filter";
	/**
	 * Item type for filter provider.
	 */
	public static final String FILTER_CONTENT_ITEM_TYPE = BASE_ITEM_TYPE + ".filter";
//	/**
//	 * Uri for filters provider.
//	 */
//	public static final Uri FILTER_URI = Uri.parse(ContentResolver.SCHEME_CONTENT + "://"
//			+ AUTHORITY + "/"
//			+ FILTERS_TABLE_NAME);
//	/**
//	 * Base uri for a specific filter. Should be appended with filter id.
//	 */
//	public static final Uri FILTER_ID_URI_BASE = Uri.parse(ContentResolver.SCHEME_CONTENT + "://"
//			+ AUTHORITY + "/"
//			+ FILTERS_TABLE_NAME + "/");





	// EXTRAS
	/**
	 * Extra key to contains infos about a sip call.<br/>
	 * @see SipCallSession
	 */
//	public static final String EXTRA_PRIVACY_CALL_KEY = "call_key";
//	public static final String EXTRA_PRIVACY_CALL_STATE = "call_state";
//	public static final String EXTRA_PRIVACY_CALL_TYPE = "call_type";
//	public static final String EXTRA_PRIVACY_IS_DAC = "is_dac";
//	public static final String EXTRA_PRIVACY_CALL_NAME = "call_name";
	public static final String EXTRA_PRIVACY_CALL_INFO = "call_info";
	public static final String EXTRA_PRIVACY_CALL_USER = "call_user";
	public static final String EXTRA_PRIVACY_IS_FLOAT = "is_float";
//	public static final String EXTRA_PRIVACY_CALL_DIR = "call_dir";
//	public static final String EXTRA_PRIVACY_CALL_NUM = "call_num";
//	public static final String EXTRA_PRIVACY_CALL_MIC = "call_mic";
//	public static final String EXTRA_PRIVACY_CALL_SDP = "call_sdp";
	
	public static final String EXTRA_PRIVACY_CALL_MCVIDEOID = "call_mcvideo_id";
	public static final String EXTRA_PRIVACY_CALL_MCDATAID = "call_mcdata_id";
//	public static final String EXTRA_PRIVACY_CALL_IP = "call_ip";
	public static final String EXTRA_CALL_INFO = "call_info";
	public static final String EXTRA_CALL_ID = "call_id";
	public static final String EXTRA_CALL_KEY = "call_key";
	public static final String EXTRA_SPEAKING_INFO = "speaking_info";
	public static final String EXTRA_MEDIA_STATUS = "media_status";

	/**
	 * Tell sip service that it's an user interface requesting for outgoing call.<br/>
	 * It's an extra to add to sip service start as string representing unique key for your activity.<br/>
	 * We advise to use your own component name {@link android.content.ComponentName} to avoid collisions.<br/>
	 * Each activity is in charge unregistering broadcasting {@link #ACTION_OUTGOING_UNREGISTER} or {@link #ACTION_DEFER_OUTGOING_UNREGISTER}<br/>
	 * 
	 * @see android.content.ComponentName
	 */
	public static final String EXTRA_OUTGOING_ACTIVITY = "outgoing_activity";

	/**
	 * Extra key to contain an string to path of a file.<br/>
	 * @see java.lang.String
	 */
	public static final String EXTRA_FILE_PATH = "file_path";

	/**
	 * Target in a sip launched call.
	 * @see #ACTION_SIP_CALL_LAUNCH
	 */
	public static final String EXTRA_SIP_CALL_TARGET = "call_target";
	/**
	 * Options of a sip launched call.
	 * @see #ACTION_SIP_CALL_LAUNCH
	 */
	public static final String EXTRA_SIP_CALL_OPTIONS = "call_options";

	/**
	 * Extra key to contain behavior of outgoing call chooser activity.<br/>
	 * In case an account is specified in the outgoing call intent with {@link SipProfile#FIELD_ACC_ID}
	 * and the application doesn't find this account,
	 * this extra parameter allows to determine what is the fallback behavior of
	 * the activity. <br/>
	 * By default {@link #FALLBACK_ASK}.
	 * Other options : 
	 */
	public static final String EXTRA_FALLBACK_BEHAVIOR = "fallback_behavior";
	/**
	 * Parameter for {@link #EXTRA_FALLBACK_BEHAVIOR}.
	 * Prompt user with other choices without calling automatically.
	 */
	public static final int FALLBACK_ASK = 0;
	/**
	 * Parameter for {@link #EXTRA_FALLBACK_BEHAVIOR}.
	 * Warn user about the fact current account not valid and exit.
	 * WARNING : not yet implemented, will behaves just like {@link #FALLBACK_ASK} for now
	 */
	public static final int FALLBACK_PREVENT = 1;
	/**
	 * Parameter for {@link #EXTRA_FALLBACK_BEHAVIOR}
	 * Automatically fallback to any other available account in case requested sip profile is not there.
	 */
	public static final int FALLBACK_AUTO_CALL_OTHER = 2;


	public static final String ACTION_PTT_DOWN = "android.intent.action.PTT_DOWN_BUTTON";

	public static final String ACTION_PTT_UP = "android.intent.action.PTT_UP_BUTTON";

	public static final String ACTION_CP_PTT = "zzx_action_ppt";

	public static final String ACTION_CP_PTT_CAPTURE = "zzx_action_capture";

	// 露香肩广播Action.
	//T1 宇龙
	public static final String T1_ACTION_PTT_DOWN = "com.yl.ptt.keydown";

	public static final String T1_ACTION_PTT_UP = "com.yl.ptt.keyup";
	
	public static final String ACTION_RECORD = "zzx_action_record";
	// 录音键广播Action.
	public static final String ACTION_MIC = "zzx_action_mic";

	// Constants
	/**
	 * Constant for success return
	 */
	public static final int SUCCESS = 0;
	/**
	 * Constant for network errors return
	 */
	public static final int ERROR_CURRENT_NETWORK = 10;

	/**
	 * Possible presence status.
	 */
	public enum PresenceStatus {
		/**
		 * Unknown status
		 */
		UNKNOWN,
		/**
		 * Online status
		 */
		ONLINE,
		/**
		 * Offline status
		 */
		OFFLINE,
		/**
		 * Busy status
		 */
		BUSY,
		/**
		 * Away status
		 */
		AWAY,
	}

	/**
	 * Current api version number.<br/>
	 * Major version x 1000 + minor version. <br/>
	 * Major version are backward compatible.
	 */
	public static final int CURRENT_API = 2005;


	/**
	 * Ensure capability of the remote sip service to reply our requests <br/>
	 * 
	 * @param service the bound service to check
	 * @return true if we can safely use the API
	 */
	public static boolean isApiCompatible(IPjsuaService service) {
		if (service != null) {
			try {
				int version = service.getVersion();
				return (Math.floor((float)version / 1000) == Math.floor((float)CURRENT_API % 1000));
			} catch (RemoteException e) {
				// We consider this is a bad api version that does not have
				// versionning at all
				return false;
			}
		}

		return false;
	}
}
